// Vec2 by Andrew Davies

"use strict";

// Constructor
function Vec2( x, y ) 
{
	this.x = x;
	this.y = y;
}

// Assign
function vec2rvAssign( rv, v )
{
	rv.x = v.x;
	rv.y = v.y;
}

function vec2Assign( v )
{
	var rv = new Vec2( v.x, v.y );
	return rv;
}

// Operators

// Multiply Scalar
function vec2rvMulS( rv, v, value )
{ 
	rv.x = v.x * value; 
	rv.y = v.y * value; 
}

function vec2MulS( v, value )
{ 
	v.x = v.x * value; 
	v.y = v.y * value; 
}

function vec2AssignMulS( v, value )
{ 
	var rv = vec2Assign( v );
	vec2MulS( rv, value );
	return rv;
}


// Multiply Vector
function vec2rvMulV( rv, v1, v2 )
{
	rv.x = v1.x * v2.x;
	rv.y = v1.y * v2.y;
}

function vec2MulV( v1, v2 )
{
	v1.x = v1.x * v2.x;
	v1.y = v1.y * v2.y;
}

function vec2AssignMulV( v1, v2 )
{ 
	var rv = vec2Assign( v1 );
	vec2MulV( rv, v2 );
	return rv;
}


// Divide Scalar
function vec2rvDivS( rv, v, value )
{
	rv = v;
	if( Math.abs( value ) > 0 )
	{
		rv.x /= value;
		rv.y /= value;
	}		
}

function vec2DivS( v, value )
{
	if( Math.abs( value ) > 0 )
	{
		v.x /= value;
		v.y /= value;
	}		
}

function vec2AssignDivS( v, value )
{ 
	var rv = vec2Assign( v );
	vec2DivS( rv, value );
	return rv;
}


// Addition Scalar
function vec2rvAddS( rv, v, value )
{
	rv.x = v.x + value;
	rv.y = v.y + value;
}

function vec2AddS( v, value )
{
	v.x = v.x + value;
	v.y = v.y + value;
}

function vec2AssignAddS( v, value )
{ 
	var rv = vec2Assign( v );
	vec2AddS( rv, value );
	return rv;
}


// Addition Vector
function vec2rvAddV( rv, v1, v2 )
{ 
	rv.x = v1.x + v2.x;
	rv.y = v1.y + v2.y;
}

function vec2AddV( v1, v2 )
{ 
	v1.x = v1.x + v2.x;
	v1.y = v1.y + v2.y;
}

function vec2AssignAddV( v1, v2 )
{ 
	var rv = vec2Assign( v1 );
	vec2AddV( rv, v2 );
	return rv;
}


// Subtraction Scalar
function vec2rvSubS( rv, v, value )
{
	rv.x = v.x - value;
	rv.y = v.y - value;
}

function vec2SubS( v, value )
{
	v.x = v.x - value;
	v.y = v.y - value;
}

function vec2AssignSubS( v, value )
{ 
	var rv = vec2Assign( v );
	vec2SubS( rv, value );
	return rv;
}


// Subtraction Vector
function vec2rvSubV( rv, v1, v2 )
{
	rv.x = v1.x - v2.x; 
	rv.y = v1.y - v2.y; 
}

function vec2SubV( v1, v2 )
{
	v1.x = v1.x - v2.x; 
	v1.y = v1.y - v2.y; 
}

function vec2AssignSubV( v1, v2 )
{ 
	var rv = vec2Assign( v1 );
	vec2SubV( rv, v2 );
	return rv;
}


// Absolute
function vec2rvAbs( rv, v )
{ 
	rv.x = Math.abs( v.x );
	rv.y = Math.abs( v.y );
}

function vec2Abs( v )
{ 
	v.x = Math.abs( v.x );
	v.y = Math.abs( v.y );
}

function vec2AssignAbs( v )
{ 
	var rv = vec2Assign( v );
	vec2Abs( rv );
	return rv;
}


// Dot product
function vec2Dot( v1, v2 )
{
	return ( v1.x * v2.x ) + ( v1.y * v2.y );
}

// Length Squared
function vec2LenSqr( v )
{
	return vec2Dot( v, v );
}


// Length
function vec2Len( v )
{ 
	return Math.sqrt( vec2Dot( v, v ) );
}


// Distance
function vec2Dist( v1, v2 )
{
	var temp = v1;
	vec2SubV( temp, v2 );
	return vec2Len( temp );
}

// Interpolate
function vec2rvLerp( rv, v1, v2, value )
{ 
	rv.x = v1.x + ( ( v2.x - v1.x ) * value );
	rv.y = v1.y + ( ( v2.y - v1.y ) * value );
}

function vec2Lerp( v1, v2, value )
{ 
	var temp = v2;
	vec2SubV( temp, v1 );
	v1.x = v1.x + ( temp.x * value );
	v1.y = v1.y + ( temp.y * value );
}

function vec2AssignLerp( v1, v2, value )
{ 
	var rv = vec2Assign( v1 );
	vec2Lerp( rv, v2, value );
	return rv;
}


// Normalise
function vec2rvNorm( rv, v )
{ 
	var vLen = vec2Len( v );
	vec2rvDivS( rv, v, vLen );
}

function vec2Norm( v )
{ 
	var vLen = vec2Len( v );
	vec2DivS( v, vLen );
}

function vec2AssignNorm( v )
{ 
	var rv = vec2Assign( v );
	vec2Norm( rv );
	return rv;
}



